/*
 *  This program is an unpublished work fully protected by the United
 *  States copyright laws and is considered a trade secret belonging
 *  to Turner Broadcasting Systems, Inc. To the extent that this work may be
 *  considered "published,"
 *  the following notice applies:
 *
 *      "Copyright 2005, Turner Broadcasting Systems, Inc."
 *
 *  Any unauthorized use, reproduction, distribution, display,
 *  modification, or disclosure of this program is strictly prohibited.
 *
 */
package com.inspectortime.webapp.util;

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.ParameterizableViewController;

import com.opensymphony.module.sitemesh.HTMLPage;
import com.opensymphony.module.sitemesh.RequestConstants;

/**
 * Prepare request for a Sitemesh decorator page written in Freemarker by
 * populating "body", "title" and other values in the object hash that are
 * visible to the decorator's freemarker template.
 * 
 * Also determines if there's an inspector-specific template component to the
 * servlet path (i.e. /context/inspectors/[client]/something.html) and if so
 * makes "inspectorCompanyShortName" and "remainingPath" available to the views
 * 
 * The specifics of how to do this has been copied from the source for class
 * com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet
 * 
 * @author mkvalsvik
 * 
 */
public class FreemarkerDecoratorController extends
		ParameterizableViewController {

	/**
	 * 
	 * @param request
	 * @param response
	 * 
	 * @return a ModelAndView pointing to the view name with the model populated
	 *         the same way that sitemesh's FreemarkerDecoratorServlet would
	 *         populate it
	 * @throws Exception
	 */
	protected ModelAndView handleRequestInternal(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		ModelAndView mv = super.handleRequestInternal(request, response);

		HTMLPage htmlPage = (HTMLPage) request
				.getAttribute(RequestConstants.PAGE);

		mv.addObject("base", request.getContextPath());

		if (htmlPage == null) {
			mv.addObject("title", "No Title");
			mv.addObject("body", "No Body");
			mv.addObject("head", "<!-- No head -->");
			return mv;
		}

		mv.addObject("title", htmlPage.getTitle());

		StringWriter buffer = new StringWriter();
		htmlPage.writeBody(buffer);
		mv.addObject("body", buffer.toString());

		buffer = new StringWriter();
		htmlPage.writeHead(buffer);
		mv.addObject("head", buffer.toString());

		mv.addObject("page", htmlPage);

		// Convert properties like meta.propA to a Map so that freemarker can
		// display <meta name="propA" content="something"/> using ${meta.propA}
		// syntax. Also supports <content tag="propB">something else</content>
		// using ${page.propB} syntax. And finally, the addition of the
		// filteredProperties means that <html propC="somevalue"> can be
		// displayed simply as ${propC}.
		Map filteredProperties = new HashMap();
		Map metaProperties = new HashMap();
		Map contentProperties = new HashMap();
		for (int i = 0; i < htmlPage.getPropertyKeys().length; i++) {
			String key = htmlPage.getPropertyKeys()[i];
			if (key.startsWith("meta.")) {
				metaProperties.put(key.substring(5), htmlPage.getProperty(key));
			} else if (key.startsWith("page.")) {
				contentProperties.put(key.substring(5), htmlPage
						.getProperty(key));
			} else {
				filteredProperties.put(key, htmlPage.getProperty(key));
			}
		}
		mv.addAllObjects(filteredProperties);
		mv.addObject("meta", metaProperties);
		mv.addObject("content", contentProperties);

		// Look for a client (inpsector company) specific part and make it
		// available to the decorator if the servlet matches the
		// /context/inspectors/[shortName]/path.html pattern
		String inspectorCompanyShortName = RequestPathUtils.extractInspectorCompanyShortNameFromPath(request);
		if (inspectorCompanyShortName != null) {
			mv.addObject("inspectorCompanyShortName", inspectorCompanyShortName);			
		} else {
			mv.addObject("inspectorCompanyShortName", RequestPathUtils.DEFAULT_INSPECTORS_VIEW_FOLDER);
		}		
		mv.addObject("remainingPath", RequestPathUtils.extractRemainingPath(request));

		return mv;
	}
}
